package org.springblade.upgrade.constant;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;

import java.io.*;
import java.nio.file.Files;
import java.util.Enumeration;

@Slf4j
public class FileUtils {

    /**
     * 解压zip文件
     *
     * @param zipOriFile
     * @throws IOException
     */
    public static File unzipAndOverride(File zipOriFile, String uploadZipPath) throws IOException {
        String fileName = zipOriFile.getName();
        fileName = fileName.substring(0, fileName.length() - 4);
        String outputBaseName = uploadZipPath + File.separator + "code";
        String newFile = outputBaseName + File.separator + fileName;
        // 检查解压目标是否存在，如果存在则删除以准备覆盖
        File potentialOutputDir = new File(uploadZipPath, outputBaseName);
        if (potentialOutputDir.exists()) {
            return potentialOutputDir;
        }
        try (ZipFile zip = new ZipFile(zipOriFile)) {
            Enumeration<ZipArchiveEntry> entries = zip.getEntries();
            while (entries.hasMoreElements()) {
                ZipArchiveEntry entry = entries.nextElement();
                File destPath = new File(outputBaseName, entry.getName());
                if (entry.isDirectory()) {
                    destPath.mkdirs();
                } else {
                    destPath.getParentFile().mkdirs();
                    try (InputStream in = zip.getInputStream(entry);
                         FileOutputStream out = new FileOutputStream(destPath)) {
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = in.read(buffer)) > 0) {
                            out.write(buffer, 0, len);
                        }
                    }
                }
            }
        }
        return new File(newFile);
    }




    /**
     * 解压zip文件
     *
     * @param zipOriFile
     * @throws IOException
     */
    public static File unzip(File zipOriFile, String uploadZipPath) throws IOException {
        String fileName = zipOriFile.getName();
        fileName = fileName.substring(0, fileName.length() - 4);
        String outputBaseName = uploadZipPath + File.separator + "code";
        String newFile = outputBaseName + File.separator + fileName;
        // 检查解压目标是否存在，如果存在则删除以准备覆盖
        File potentialOutputDir = new File(uploadZipPath, outputBaseName);
        if (potentialOutputDir.exists()) {
            return potentialOutputDir;
        }
        try (ZipFile zip = new ZipFile(zipOriFile)) {
            Enumeration<ZipArchiveEntry> entries = zip.getEntries();
            while (entries.hasMoreElements()) {
                ZipArchiveEntry entry = entries.nextElement();
                File destPath = new File(outputBaseName, entry.getName());
                if (entry.isDirectory()) {
                    destPath.mkdirs();
                } else {
                    destPath.getParentFile().mkdirs();
                    try (InputStream in = zip.getInputStream(entry);
                         FileOutputStream out = new FileOutputStream(destPath)) {
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = in.read(buffer)) > 0) {
                            out.write(buffer, 0, len);
                        }
                    }
                }
            }
        }
        return new File(newFile);
    }


    /**
     * 解压tar.gz文件
     *
     * @param tarGzOriFile
     * @throws IOException
     */
    public static File unTarGz(File tarGzOriFile, String uploadZipPath) throws IOException {
        String fileName = tarGzOriFile.getName();
        fileName = fileName.substring(0, fileName.length() - 6);
        String outputBaseName = uploadZipPath + File.separator + "code";
        String newFile = outputBaseName + File.separator + fileName;
        // 检查解压目标是否存在，如果存在则删除以准备覆盖
        File potentialOutputDir = new File(uploadZipPath, outputBaseName);
        if (potentialOutputDir.exists()) {
            return potentialOutputDir;
        }
        // 处理 .tar.gz 文件
        try (InputStream fileStream = Files.newInputStream(tarGzOriFile.toPath());
             BufferedInputStream bufferedIn = new BufferedInputStream(fileStream);
             TarArchiveInputStream tarIn = new TarArchiveInputStream(new GzipCompressorInputStream(bufferedIn))) {

            TarArchiveEntry entry;
            while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
                String entryName = entry.getName();
                File outputFile = new File(outputBaseName, entryName);

                if (entry.isDirectory()) {
                    // 如果是目录，则创建它
                    if (!outputFile.exists()) {
                        outputFile.mkdirs();
                    }
                } else {
                    // 确保目标文件的父目录存在
                    outputFile.getParentFile().mkdirs();

                    try (FileOutputStream out = new FileOutputStream(outputFile)) {
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = tarIn.read(buffer)) > 0) {
                            out.write(buffer, 0, len);
                        }
                    }
                }
            }
        }
        return new File(newFile);
    }
}
